<script setup lang="ts">
import axios from "axios";
import {nextTick, onMounted, ref} from "vue";
import SendSvg from "@/svg/sendSvg.vue";
import {ElScrollbar} from "element-plus";
import ChildBoth from "@/Components/ChildBoth.vue";
import LeftList from "@/Components/LeftList.vue";
import RightUserPhoto from "@/Components/RightUserPhoto.vue";
import UndoRedoSearch from "@/Components/UndoRedoSearch.vue";
import SongBottom from "@/Components/SongBottom.vue";
import {answer, qaArr, question} from "@/store/songStore";
import CarbonKnowSvg from "@/svg/CarbonKnowSvg.vue";
import ChatSettingSvg from "@/svg/ChatSettingSvg.vue";
import router from "@/Router";
import {directChineseChat} from "@/Network/chatApi";
import LoadingSvg from "@/svg/LoadingSvg.vue";


let showCarbonTipInfo = ref(true)
let preQArr = ref(["什么是碳资产，如何定义它？","为什么要管理碳资产","碳资产发展对国家的影响","碳资产在生活中的例子","碳服务有什么","如何管理碳资产",])
let waitingSign = ref(false)
const innerRef = ref<HTMLDivElement>()
const scrollbarRef = ref<InstanceType<typeof ElScrollbarType>>()

nextTick(()=>{
  if(innerRef.value!.clientHeight > 548){
    scrollbarRef.value!.setScrollTop(innerRef.value!.clientHeight)
  }
})

function newToQuestion(){
  showCarbonTipInfo.value = false;
  let userWord = {
    person:"user",
    words:question.value
  }
  qaArr.value.push(userWord)
  directChineseChat(question.value).then(res=>{
    console.log(res.data.choices[0].message.content)
    answer.value = res.data.choices[0].message.content
    let gptWord = {
      person:"gpt",
      words:answer.value
    }
    qaArr.value.push(gptWord)
    question.value = ""
    nextTick(()=>{
      if(innerRef.value!.clientHeight > 548){
        scrollbarRef.value!.setScrollTop(innerRef.value!.clientHeight)
      }
    })
  })
  //问题会先生成，因此外部需要一个异步的滑动
  nextTick(()=>{
    if(innerRef.value!.clientHeight > 548){
      scrollbarRef.value!.setScrollTop(innerRef.value!.clientHeight)
    }
  })
}

function getUserCss(i){
  let v = [];
  if (i.person == "user") {
    v.push("userTalkSpan");

  }else {
    v.push("gptTalkSpan");

  }
  return v;
}
function clickedPreQ(preQ:string){
  question.value = preQ
  // newToQuestion()
  // newToQuestion()
  streamFetchChineseChat()
}
function toSetting(){
  router.push("/chat_setting")
}


async function streamFetchChineseChat(){
  showCarbonTipInfo.value = false;
  let userWord = {
    person:"user",
    words:question.value
  }
  qaArr.value.push(userWord)
  waitingSign.value = true
  nextTick(()=>{
    if(innerRef.value!.clientHeight > 548){
      scrollbarRef.value!.setScrollTop(innerRef.value!.clientHeight)
    }
  })

  try{
    // 发送请求
    let response = await fetch("https://api.closeai-proxy.xyz/v1/chat/completions",
        {
          method: "post",
          responseType: "stream",
          headers: {
            "Authorization": "Bearer " + 'sk-tHy9pL8JW1QIPM3GMNGCQIitk3rjKtq8j0k2HxGJ6dh9qCvC',
            "Content-Type": "application/json",
          },
          body: JSON.stringify({
            "model": "gpt-3.5-turbo",
            "messages": [{"role": "user", "content": JSON.stringify(question.value)+" (中文回答且不能超过50字)"}],
            "stream":true
          }),
        }
    );

    // ok字段判断是否成功获取到数据流
    if (!response.ok) {
      console.log("Network response was not ok");
    }
    // 用来获取一个可读的流的读取器（Reader）以流的方式处理响应体数据
    const reader = response.body.getReader();
    // 将流中的字节数据解码为文本字符串
    const textDecoder = new TextDecoder();
    let result = true;
    let sqlValue = ''
    let count = 0

    while (result) {
      // done表示流是否已经完成读取  value包含读取到的数据块
      const { done, value } = await reader.read();
      if (done) {
        result = false;
        break;
      }
      // 拿到的value就是后端分段返回的数据，大多是以data:开头的字符串
      // 需要通过decode方法处理数据块，例如转换为文本或进行其他操作
      textDecoder
          .decode(value)
          .split("\n")
          .forEach((val) => {
            if (!val) return;
            try {
              // 后端返回的流式数据一般都是以data:开头的字符，排除掉data:后就是需要的数据,并将其序列化JSON。parse方便操作键值
              // 具体返回结构可以跟后端约定
              let text = val?.replace("data:", "") || ""
              console.log(text)
              let singleAns = JSON.parse(text)
              // console.log( "输出返回的:"+singleAns.choices[0].delta.content);
              if(singleAns.choices[0].finish_reason !="stop"){//未结束时为null
                sqlValue += singleAns.choices[0].delta.content;

                answer.value = sqlValue
                let gptWord = {
                  person:"gpt",
                  words:answer.value
                }
                if(count==0){
                  waitingSign.value = false
                  qaArr.value.push(gptWord)
                  count +=1
                }else{
                  qaArr.value.splice(qaArr.value.length-1,1,gptWord)
                }

                nextTick(()=>{
                  if(innerRef.value!.clientHeight > 548){
                    scrollbarRef.value!.setScrollTop(innerRef.value!.clientHeight)
                  }
                })
                console.log(sqlValue)
              }
            } catch (err) {}
          });
    }
    question.value = ""
    console.log(sqlValue,'输出最终返回答案')
  } catch(err) {}
}


</script>

<template>
  <div class="body flex">
    <div class="main grow h-200 flex flex-col overflow-auto pb-15 mx-3 ">
      <div class="mt-15  w-full h-150   flex flex-col justify-start items-center gap-2">
        <template v-if="showCarbonTipInfo==true">
          <div class="w-94% grow flex justify-center items-center">
            <div class="flex flex-col w-90% h-full justify-center items-center gap-4">
              <carbon-know-svg class="h-32 w-32 text-green-5"></carbon-know-svg>
              <p class="text-7">你好，我是碳知道</p>
              <p class="w-150 text-center">我是基于深度学习和自然语言处理技术的生成式AI产品，可以帮您解答碳资产领域相关的问题，提高您的工作学习效率。</p>
              <div class="mt-4 flex w-full justify-start items-start">
                <div class="text-gray-4 select-none">您可以试试这样问我</div>
              </div>
              <div class="w-full grid grid-cols-2 gap-4">
                <div v-for="ele in preQArr">
                  <div class="bg-white p-2 rounded-lg hover:bg-green-4 hover:text-white cursor-pointer"
                       @click="clickedPreQ(ele)"
                  >
                    {{ele}}
                  </div>
                </div>
              </div>

            </div>
          </div>
        </template>

        <template v-else>
          <div class="w-full mb--1" >
            <el-scrollbar ref="scrollbarRef" height="548px" always class="pl-8 pr-5">
              <div ref="innerRef">
                <div v-for="i in qaArr" :class="i.person=='user'?'userTalk':'gptTalk'"
                     class="w-full"
                >
                  <div v-html="i.words" class=" p-3 rounded-t-lg text-5 "
                       :class="getUserCss(i)">
                  </div>

                </div>
              </div>
              <div v-show="waitingSign">
                <div class="gptTalk w-full"
                >
                  <div class="gptTalkSpan p-3 rounded-t-lg">
                    <loading-svg class="animate-spin text-green-5 w-6 h-6  "></loading-svg>
                  </div>
                </div>
              </div>

            </el-scrollbar>
            <!-- 根据vue对象中的数组，遍历出对应的标签。 -->

          </div>
        </template>

        <div class="search w-95% h-12     flex justify-start items-center gap-4">
          <button class=" h-13 w-13 border-3 border-white bg-green-4 rounded-full
            hover:bg-green-5 flex justify-center items-center"
                  @click="toSetting"
          >
            <chat-setting-svg class="w-8 h-8 text-white"></chat-setting-svg>
          </button>

          <input class=" grow   bg-white  outline-none h-12 rounded-xl border-2
      border-gray-3   hover:border-green-4 hover:border-3
      text-gray-5 text-5 pl-3"
                 placeholder="请向我提问吧 ^_^"
                 v-model="question"
                 @keyup.enter="streamFetchChineseChat"
          />
          <button class="h-13 w-13 border-3 border-white bg-green-4 rounded-full
      hover:bg-green-5 flex justify-center items-center"
                  @click="streamFetchChineseChat"
          >
            <send-svg class="w-8 h-8 mr-0.7"></send-svg>
          </button>
        </div>
      </div>
    </div>
  </div>

</template>

<style scoped>
.userTalk{
  @apply mb-3  flex justify-end items-start ;
}

.gptTalk{
  @apply mb-3  flex justify-start items-start ;
}

.userTalkSpan{
  @apply mr-5  bg-green-5 ml-100  mb-4 border-3 text-white  flex justify-end items-center rounded-l-lg break-all break-words;
}

.gptTalkSpan{
  @apply  bg-white border-3  mr-100 mb-4  text-gray-7   flex justify-start items-center rounded-r-lg break-all break-words ;
}


</style>